/*
 * @Author: OreoWang
 * @Email: ihc523@163.com
 * @Date: 2022-03-22 21:47:14
 * @LastEditors: OreoWang
 * @LastEditTime: 2022-04-26 17:10:32
 * @Description: 独立子节点，可直接添加到节点树上。 相对 element 元素，元素只能附加到 entity 上。
 */

import { BehaviorNode } from "./behavior-node";
import { BehaviorStatus } from "./behavior-status";

export class BehaviorEntity extends BehaviorNode {
    statusCondition = BehaviorStatus.None;

    abort(){
        if(this.status==BehaviorStatus.Running){
            this.disable();
        }
        return super.abort();
    }

    /**
     * 节点执行逻辑。顺序为：
     * @describe execute => condition(true) -> service -> self -> decorator => return
     * @describe execute => condition(false) => return
     * @param status 
     * @returns 
     */
	execute(status?: BehaviorStatus){
        if(typeof status == 'undefined'){
            status = this.status==BehaviorStatus.Running ? BehaviorStatus.Running : BehaviorStatus.None;
        }
        status = this.executeCondition(status);
        //如果节点执行条件不成立
        if(status == BehaviorStatus.Failure){
            if(this.status==BehaviorStatus.Running){
                this.disable();
            }
            this.status = status;
            return this.status;
        }

        this.enter();

        if(this.status != BehaviorStatus.Running){
            this.enable();
        }

        this.executeServices(status);

        this.status = status = this.update(status);

        this.logLifeStatus("execute");
        
        this.status = status = this.executeDecorator(status);
        
        if(status == BehaviorStatus.Running){
        }
        else{
            if(status == BehaviorStatus.Failure){  
            }
            this.disable();     
        }

        this.exit();
          
        return this.status;
    }

    /**
     * 前置条件装饰器
     * @param status 
     * @returns 
     */
    protected executeCondition(status: BehaviorStatus){
        let array = this.decorators;
        //装饰器的执行顺序都是从最后一个开始往上执行的
        for (let index = array.length-1; index>=0; index--) {
            const element = array[index];
            if(element.isCondition){
                //将上一个 status 作为参数传入
                //该参数使用比较灵活，视具体的 execute 方法实现而定
                //比如可实现类似 ConditionalInverter 结果反转逻辑
                status = element.execute(status);
            }
        }
        //记录本次条件状态，如果需要中断，则下次tick会判断状态是否发生改变
        this.statusCondition = status;
        return status;
    }
    /**
     * 后置普通装饰器
     * @param status 
     * @returns 
     */
    protected executeDecorator(status: BehaviorStatus){
        let array = this.decorators;
        //装饰器的执行顺序都是从最后一个开始往上执行的
        for (let index = array.length-1; index>=0; index--) {
            const element = array[index];
            if(!element.isCondition){
                //将上一个 status 作为参数传入
                //该参数使用比较灵活，视具体的 execute 方法实现而定
                //比如可实现类似 Inverter 结果反转逻辑
                status = element.execute(status);
            }
        }
        return status;
    }
    
    /**
     * 节点服务，每次 tick 周期都会执行
     * @param status 
     */
    protected executeServices(status: BehaviorStatus){
        const array = this.services;
        for (let index = array.length-1; index>=0; index--) {
            const element = array[index];
            element.update(status);
        }
    }

    public checkCondition(status: BehaviorStatus){
        let modify = false;
        let array = this.decorators;
        for (let index = array.length-1; index>=0; index--) {
            const element = array[index];
            if(element.isCondition){
                status = element.execute(status);
            }
        }
        if(this.statusCondition != status){
            modify = true;
        }

        return modify;
    }
}